#pragma once

#include <string>
#include <sstream>
#include <strstream>
#include <XUtil/XStr.hpp>
#include <mdbase.h>

namespace mdb
{
    namespace FieldOp
    {
		template<typename TField>
		static inline MDB_STATUS GetValue(const char* data, const TField* field, size_t field_num, char* value)
		{
			if (!data) {
				return MDB_STATUS_INVALID_PARAM;
			}
			if (!field || !field_num || !value) {
				return MDB_STATUS_INVALID_PARAM;
			}
			for (size_t i = 0; i < field_num; i++)
			{
				ASSERT(field[i].size > 0);
				memcpy((char*)value + field[i].offset, (const char*)data + field[i].offset, field[i].size);
			}
			return MDB_STATUS_OK;
		}

		template<typename TField>
		static inline MDB_STATUS SetValue(char* data, const TField* field, size_t field_num, const char* value)
		{
			if (!data) {
				return MDB_STATUS_INVALID_PARAM;
			}
			if (!field || !field_num || !value) {
				return MDB_STATUS_INVALID_PARAM;
			}
			for (size_t i = 0; i < field_num; i++)
			{
				ASSERT(field[i].size > 0);
				memcpy((char*)data + field[i].offset, (const char*)value + field[i].offset, field[i].size);
			}
			return MDB_STATUS_OK;
		}

		template<typename TField>
        static inline MDB_STATUS GetValueAs(const char* data, const TField* field, size_t field_num, char* value, size_t size)
        {
            if(!data) {
                return MDB_STATUS_INVALID_PARAM;
            }
            if(!field || !field_num || !value || !size) {
                return MDB_STATUS_INVALID_PARAM;
            }
            ASSERT(MDBFieldCalcSize(field,field_num) <= size);
            size_t offset = 0;
            for(size_t i = 0; i < field_num; i++)
            {
                ASSERT(field[i].size > 0);
                memcpy((char*)value + offset, (const char*)data + field[i].offset, field[i].size);
                offset += field[i].size;
            }
            return MDB_STATUS_OK;
        }

		template<typename TField>
        static inline MDB_STATUS SetValueAs(char* data, const TField* field, size_t field_num, const char* value, size_t size)
        {
            if(!data) {
                return MDB_STATUS_INVALID_PARAM;
            }
            if(!field || !field_num || !value || !size) {
                return MDB_STATUS_INVALID_PARAM;
            }
            ASSERT(MDBFieldCalcSize(field,field_num) <= size);
            size_t offset = 0;
            for(size_t i = 0; i < field_num; i++)
            {
                ASSERT(field[i].size > 0);
                memcpy((char*)data + field[i].offset, (const char*)value + offset, field[i].size);
                offset += field[i].size;
            }
            return MDB_STATUS_OK;
        }

		template<typename TField>
		static inline size_t Diff(const TField* field, size_t field_num, const char* x, const char* y, TField* out)
        {
            ASSERT(field && field_num && x && y);
			{
				size_t diff = 0;
				for (size_t i = 0; i < field_num; ++i)
				{
					{
						switch (field[i].type)
						{
						case MDB_FIELD_TYPE_CHAR:
							if (*(char *)((char *)x + field[i].offset) != *(char *)((char *)y + field[i].offset))
							{
								out[diff++] = field[i];
							}
							break;
						case MDB_FIELD_TYPE_BYTE:
							if (*(byte *)((char *)x + field[i].offset) != *(byte *)((char *)y + field[i].offset))
							{
								out[diff++] = field[i];
							}
							break;
						case MDB_FIELD_TYPE_INT16:
							if (*(int16_t *)((char *)x + field[i].offset) != *(int16_t *)((char *)y + field[i].offset))
							{
								out[diff++] = field[i];
							}
							break;
						case MDB_FIELD_TYPE_UINT16:
							if (*(uint16_t *)((char *)x + field[i].offset) != *(uint16_t *)((char *)y + field[i].offset))
							{
								out[diff++] = field[i];
							}
							break;
						case MDB_FIELD_TYPE_INT32:
							if (*(int32_t *)((char *)x + field[i].offset) != *(int32_t *)((char *)y + field[i].offset))
							{
								out[diff++] = field[i];
							}
							break;
						case MDB_FIELD_TYPE_UINT32:
							if (*(uint32_t *)((char *)x + field[i].offset) != *(uint32_t *)((char *)y + field[i].offset))
							{
								out[diff++] = field[i];
							}
							break;
						case MDB_FIELD_TYPE_INT64:
							if (*(int64_t *)((char *)x + field[i].offset) != *(int64_t *)((char *)y + field[i].offset))
							{
								out[diff++] = field[i];
							}
							break;
						case MDB_FIELD_TYPE_UINT64:
							if (*(uint64_t *)((char *)x + field[i].offset) != *(uint64_t *)((char *)y + field[i].offset))
							{
								out[diff++] = field[i];
							}
							break;
						case MDB_FIELD_TYPE_FLOAT:
							if (*(float *)((char *)x + field[i].offset) != *(float *)((char *)y + field[i].offset))
							{
								out[diff++] = field[i];
							}
							break;
						case MDB_FIELD_TYPE_DOUBLE:
							if (*(double *)((char *)x + field[i].offset) != *(double *)((char *)y + field[i].offset))
							{
								out[diff++] = field[i];
							}
							break;
						case MDB_FIELD_TYPE_STRING:
							if (strncmp((char *)x + field[i].offset, (char *)y + field[i].offset, field[i].size) != 0)
							{
								out[diff++] = field[i];
							}
							break;
						case MDB_FIELD_TYPE_BLOB:
							if (memcmp((char *)x + field[i].offset, (char *)y + field[i].offset, field[i].size) != 0)
							{
								out[diff++] = field[i];
							}
							break;
						default:
							ASSERT(0);
							break;
						}
					}
				}
				return diff;
			}
			return 0;
        }
		template<typename TField>
		static inline bool Less(const TField* field, size_t field_num, const char* x, const char* y)
		{
			ASSERT(field && field_num && x && y);
			{
				for (size_t i = 0; i < field_num; ++i)
				{
					{
						switch (field[i].type)
						{
						case MDB_FIELD_TYPE_CHAR:
							if (*(char *)((char *)x + field[i].offset) >= *(char *)((char *)y + field[i].offset))
							{
								return false;
							}
							break;
						case MDB_FIELD_TYPE_BYTE:
							if (*(byte *)((char *)x + field[i].offset) >= *(byte *)((char *)y + field[i].offset))
							{
								return false;
							}
							break;
						case MDB_FIELD_TYPE_INT16:
							if (*(int16_t *)((char *)x + field[i].offset) >= *(int16_t *)((char *)y + field[i].offset))
							{
								return false;
							}
							break;
						case MDB_FIELD_TYPE_UINT16:
							if (*(uint16_t *)((char *)x + field[i].offset) >= *(uint16_t *)((char *)y + field[i].offset))
							{
								return false;
							}
							break;
						case MDB_FIELD_TYPE_INT32:
							if (*(int32_t *)((char *)x + field[i].offset) >= *(int32_t *)((char *)y + field[i].offset))
							{
								return false;
							}
							break;
						case MDB_FIELD_TYPE_UINT32:
							if (*(uint32_t *)((char *)x + field[i].offset) >= *(uint32_t *)((char *)y + field[i].offset))
							{
								return false;
							}
							break;
						case MDB_FIELD_TYPE_INT64:
							if (*(int64_t *)((char *)x + field[i].offset) >= *(int64_t *)((char *)y + field[i].offset))
							{
								return false;
							}
							break;
						case MDB_FIELD_TYPE_UINT64:
							if (*(uint64_t *)((char *)x + field[i].offset) >= *(uint64_t *)((char *)y + field[i].offset))
							{
								return false;
							}
							break;
						case MDB_FIELD_TYPE_FLOAT:
							if (*(float *)((char *)x + field[i].offset) >= *(float *)((char *)y + field[i].offset))
							{
								return false;
							}
							break;
						case MDB_FIELD_TYPE_DOUBLE:
							if (*(double *)((char *)x + field[i].offset) >= *(double *)((char *)y + field[i].offset))
							{
								return false;
							}
							break;
						case MDB_FIELD_TYPE_STRING:
							if (strncmp((char *)x + field[i].offset, (char *)y + field[i].offset, field[i].size) >= 0)
							{
								return false;
							}
							break;
						case MDB_FIELD_TYPE_BLOB:
							if (memcmp((char *)x + field[i].offset, (char *)y + field[i].offset, field[i].size) >= 0)
							{
								return false;
							}
							break;
						default:
							ASSERT(0);
							break;
						}
					}
				}
			}
			return true;
		}

		/*static inline bool Less(const MDB_FIELD* x_field, size_t x_field_num, const char* x, const MDB_FIELD* y_field, size_t y_field_num, const char* y)
		{
			ASSERT(x_field && x_field_num && x && y_field && y_field_num && y);
			if (x_field_num < y_field_num) {
				return true;
			}
			else if (x_field_num > y_field_num) {
				return false;
			} else {
				for (size_t i = 0; i < x_field_num; ++i)
				{
					{
						if (x_field[i].id < y_field[i].id) {
							return true;
						}
						else if (x_field[i].id < y_field[i].id) {
							return false;
						} else {
							switch (x_field[i].type)
							{
							case MDB_FIELD_TYPE_CHAR:
								if (*(char *)((char *)x + x_field[i].offset) >= *(char *)((char *)y + y_field[i].offset))
								{
									return false;
								}
								break;
							case MDB_FIELD_TYPE_BYTE:
								if (*(byte *)((char *)x + x_field[i].offset) >= *(byte *)((char *)y + y_field[i].offset))
								{
									return false;
								}
								break;
							case MDB_FIELD_TYPE_INT16:
								if (*(int16_t *)((char *)x + x_field[i].offset) >= *(int16_t *)((char *)y + y_field[i].offset))
								{
									return false;
								}
								break;
							case MDB_FIELD_TYPE_UINT16:
								if (*(uint16_t *)((char *)x + x_field[i].offset) >= *(uint16_t *)((char *)y + y_field[i].offset))
								{
									return false;
								}
								break;
							case MDB_FIELD_TYPE_INT32:
								if (*(int32_t *)((char *)x + x_field[i].offset) >= *(int32_t *)((char *)y + y_field[i].offset))
								{
									return false;
								}
								break;
							case MDB_FIELD_TYPE_UINT32:
								if (*(uint32_t *)((char *)x + x_field[i].offset) >= *(uint32_t *)((char *)y + y_field[i].offset))
								{
									return false;
								}
								break;
							case MDB_FIELD_TYPE_INT64:
								if (*(int64_t *)((char *)x + x_field[i].offset) >= *(int64_t *)((char *)y + y_field[i].offset))
								{
									return false;
								}
								break;
							case MDB_FIELD_TYPE_UINT64:
								if (*(uint64_t *)((char *)x + x_field[i].offset) >= *(uint64_t *)((char *)y + y_field[i].offset))
								{
									return false;
								}
								break;
							case MDB_FIELD_TYPE_FLOAT:
								if (*(float *)((char *)x + x_field[i].offset) >= *(float *)((char *)y + y_field[i].offset))
								{
									return false;
								}
								break;
							case MDB_FIELD_TYPE_DOUBLE:
								if (*(double *)((char *)x + x_field[i].offset) >= *(double *)((char *)y + y_field[i].offset))
								{
									return false;
								}
								break;
							case MDB_FIELD_TYPE_STRING:
								if (strncmp((char *)x + x_field[i].offset, (char *)y + y_field[i].offset, y_field[i].size) >= 0)
								{
									return false;
								}
								break;
							case MDB_FIELD_TYPE_BLOB:
								if (memcmp((char *)x + x_field[i].offset, (char *)y + y_field[i].offset, y_field[i].size) >= 0)
								{
									return false;
								}
								break;
							default:
								ASSERT(0);
								break;
							}
						}
					}
				}
			}
			return true;
		}*/

		template<typename Ty>
		static inline MDB_FIELD_TYPE Type()
		{
			//constexpr 
			if (typeid(Ty) == typeid(char)) {
				return MDB_FIELD_TYPE_CHAR;
			}
			else if (typeid(Ty) == typeid(byte)) {
				return MDB_FIELD_TYPE_BYTE;
			}
			else if (typeid(Ty) == typeid(int16_t)) {
				return MDB_FIELD_TYPE_INT16;
			}
			else if (typeid(Ty) == typeid(uint16_t)) {
				return MDB_FIELD_TYPE_UINT16;
			}
			else if (typeid(Ty) == typeid(int32_t)) {
				return MDB_FIELD_TYPE_INT32;
			}
			else if (typeid(Ty) == typeid(uint32_t)) {
				return MDB_FIELD_TYPE_UINT32;
			}
			else if (typeid(Ty) == typeid(int64_t)) {
				return MDB_FIELD_TYPE_INT64;
			}
			else if (typeid(Ty) == typeid(uint64_t)) {
				return MDB_FIELD_TYPE_UINT64;
			}
			else if (typeid(Ty) == typeid(float)) {
				return MDB_FIELD_TYPE_FLOAT;
			}
			else if (typeid(Ty) == typeid(double)) {
				return MDB_FIELD_TYPE_DOUBLE;
			}
			else if (typeid(Ty) == typeid(char*)) {
				return MDB_FIELD_TYPE_STRING;
			}
			else if (typeid(Ty) == typeid(void*)) {
				return MDB_FIELD_TYPE_BLOB;
			}
			return MDB_FIELD_TYPE_UNKNOWN;
		}

		template<typename Ty>
		static inline void ToT(const void* field_data, const uint32_t field_type, Ty* value)
		{
			ASSERT(field_data && value);
			switch (field_type)
			{
			case MDB_FIELD_TYPE_CHAR:
				*value = *((const char*)field_data);
				break;
			case MDB_FIELD_TYPE_BYTE:
				*value = *(byte*)((const char*)field_data);
				break;
			case MDB_FIELD_TYPE_INT16:
				*value = *(int16_t*)((const char*)field_data);
				break;
			case MDB_FIELD_TYPE_UINT16:
				*value = *(uint16_t*)((const char*)field_data);
				break;
			case MDB_FIELD_TYPE_INT32:
				*value = *(int32_t*)((const char*)field_data);
				break;
			case MDB_FIELD_TYPE_UINT32:
				*value = *(uint32_t*)((const char*)field_data);
				break;
			case MDB_FIELD_TYPE_INT64:
				*value = *(uint64_t*)((const char*)field_data);
				break;
			case MDB_FIELD_TYPE_UINT64:
				*value = *(uint64_t*)((const char*)field_data);
				break;
			case MDB_FIELD_TYPE_FLOAT:
				*value = *(float*)((const char*)field_data);
				break;
			case MDB_FIELD_TYPE_DOUBLE:
				*value = *(double*)((const char*)field_data);
				break;
			case MDB_FIELD_TYPE_STRING:
			case MDB_FIELD_TYPE_BLOB:
				if (typeid(Ty) == typeid(double) || typeid(Ty) == typeid(float)) {
					*value = std::atof((const char*)field_data);
				}
				else {
					*value = std::atoll((const char*)field_data);
				}
				break;
			default:
				*value = 0;
				break;
			}
		}

		static inline void ToStr(const void* field_data, const uint32_t field_type, const uint32_t field_size, char* value, uint32_t size, const char* format = nullptr)
		{
			ASSERT(field_data && field_size > 0 && value && size > 0);
			memset(value, 0, size);
			switch (field_type)
			{
			case MDB_FIELD_TYPE_CHAR:
				snprintf(value, size, format ? format : "%c", *((const char*)field_data));
				break;
			case MDB_FIELD_TYPE_BYTE:
				snprintf(value, size, format ? format : "%d", *(byte*)((const char*)field_data));
				break;
			case MDB_FIELD_TYPE_INT16:
				snprintf(value, size, format ? format : "%d", *(int16_t*)((const char*)field_data));
				break;
			case MDB_FIELD_TYPE_UINT16:
				snprintf(value, size, format ? format : "%d", *(uint16_t*)((const char*)field_data));
				break;
			case MDB_FIELD_TYPE_INT32:
				snprintf(value, size, format ? format : "%d", *(int32_t*)((const char*)field_data));
				break;
			case MDB_FIELD_TYPE_UINT32:
				snprintf(value, size, format ? format : "%u", *(uint32_t*)((const char*)field_data));
				break;
			case MDB_FIELD_TYPE_INT64:
				snprintf(value, size, format ? format : "%lld", *(int64_t*)((const char*)field_data));
				break;
			case MDB_FIELD_TYPE_UINT64:
				snprintf(value, size, format ? format : "%llu", *(uint64_t*)((const char*)field_data));
				break;
			case MDB_FIELD_TYPE_FLOAT:
				snprintf(value, size, format ? format : "%f", *(float*)((const char*)field_data));
				break;
			case MDB_FIELD_TYPE_DOUBLE:
				snprintf(value, size, format ? format : "%f", *(double*)((const char*)field_data));
				break;
			case MDB_FIELD_TYPE_STRING:
				if (format) {
					snprintf(value, size, format, (const char*)field_data);
					break;
				}
			case MDB_FIELD_TYPE_BLOB:
				memcpy(value, (const char*)field_data, std::min<>(field_size, size));
				break;
			default:
				break;
			}
		}

		template<typename TField>
		static inline MDB_STATUS GetValueAsField(const char* data, const TField* field, const TField* as_field, size_t field_num, char* value, size_t size)
		{
			if (!data) {
				return MDB_STATUS_INVALID_PARAM;
			}
			if (!field || !as_field || !field_num || !value || !size) {
				return MDB_STATUS_INVALID_PARAM;
			}
			ASSERT(MDBFieldCalcSize(as_field, field_num) <= size);
			for (size_t i = 0; i < field_num; i++)
			{
				ASSERT(field[i].size > 0 && as_field[i].size > 0);
				//memcpy((char*)value + as_field[i].offset, (const char*)data + field[i].offset, field[i].size);
				switch (as_field[i].type)
				{
				case MDB_FIELD_TYPE_CHAR:
					ToT<char>((const char*)data + field[i].offset, field[i].type, (char*)value + as_field[i].offset);
					break;
				case MDB_FIELD_TYPE_BYTE:
					ToT<byte>((const char*)data + field[i].offset, field[i].type, (byte*)((char*)value + as_field[i].offset));
					break;
				case MDB_FIELD_TYPE_INT16:
					ToT<int16_t>((const char*)data + field[i].offset, field[i].type, (int16_t*)((char*)value + as_field[i].offset));
					break;
				case MDB_FIELD_TYPE_UINT16:
					ToT<uint16_t>((const char*)data + field[i].offset, field[i].type, (uint16_t*)((char*)value + as_field[i].offset));
					break;
				case MDB_FIELD_TYPE_INT32:
					ToT<int32_t>((const char*)data + field[i].offset, field[i].type, (int32_t*)((char*)value + as_field[i].offset));
					break;
				case MDB_FIELD_TYPE_UINT32:
					ToT<uint32_t>((const char*)data + field[i].offset, field[i].type, (uint32_t*)((char*)value + as_field[i].offset));
					break;
				case MDB_FIELD_TYPE_INT64:
					ToT<int64_t>((const char*)data + field[i].offset, field[i].type, (int64_t*)((char*)value + as_field[i].offset));
					break;
				case MDB_FIELD_TYPE_UINT64:
					ToT<uint64_t>((const char*)data + field[i].offset, field[i].type, (uint64_t*)((char*)value + as_field[i].offset));
					break;
				case MDB_FIELD_TYPE_FLOAT:
					ToT<float>((const char*)data + field[i].offset, field[i].type, (float*)((char*)value + as_field[i].offset));
					break;
				case MDB_FIELD_TYPE_DOUBLE:
					ToT<double>((const char*)data + field[i].offset, field[i].type, (double*)((char*)value + as_field[i].offset));
					break;
				case MDB_FIELD_TYPE_STRING:
				case MDB_FIELD_TYPE_BLOB:
					ToStr((const char*)data + field[i].offset, field[i].type, field[i].size, (char*)value + as_field[i].offset, as_field[i].size);
					break;
				default:
					break;
				}
			}
			return MDB_STATUS_OK;
		}

		template<typename TField>
		static inline MDB_STATUS SetValueAsField(char* data, const TField* field, const TField* as_field, size_t field_num, const char* value, size_t size)
		{
			if (!data) {
				return MDB_STATUS_INVALID_PARAM;
			}
			if (!field || !as_field || !field_num || !value || !size) {
				return MDB_STATUS_INVALID_PARAM;
			}
			ASSERT(MDBFieldCalcSize(as_field, field_num) <= size);
			for (size_t i = 0; i < field_num; i++)
			{
				ASSERT(field[i].size > 0 && as_field[i].size > 0);
				//memcpy((char*)data + field[i].offset, (const char*)value + as_field[i].offset, field[i].size);
				switch (field[i].type)
				{
				case MDB_FIELD_TYPE_CHAR:
					ToT<char>((const char*)value + as_field[i].offset, as_field[i].type, (char*)data + field[i].offset);
					break;
				case MDB_FIELD_TYPE_BYTE:
					ToT<byte>((const char*)value + as_field[i].offset, as_field[i].type, (byte*)((char*)data + field[i].offset));
					break;
				case MDB_FIELD_TYPE_INT16:
					ToT<int16_t>((const char*)value + as_field[i].offset, as_field[i].type, (int16_t*)((char*)data + field[i].offset));
					break;
				case MDB_FIELD_TYPE_UINT16:
					ToT<uint16_t>((const char*)value + as_field[i].offset, as_field[i].type, (uint16_t*)((char*)data + field[i].offset));
					break;
				case MDB_FIELD_TYPE_INT32:
					ToT<int32_t>((const char*)value + as_field[i].offset, as_field[i].type, (int32_t*)((char*)data + field[i].offset));
					break;
				case MDB_FIELD_TYPE_UINT32:
					ToT<uint32_t>((const char*)value + as_field[i].offset, as_field[i].type, (uint32_t*)((char*)data + field[i].offset));
					break;
				case MDB_FIELD_TYPE_INT64:
					ToT<int64_t>((const char*)value + as_field[i].offset, as_field[i].type, (int64_t*)((char*)data + field[i].offset));
					break;
				case MDB_FIELD_TYPE_UINT64:
					ToT<uint64_t>((const char*)value + as_field[i].offset, as_field[i].type, (uint64_t*)((char*)data + field[i].offset));
					break;
				case MDB_FIELD_TYPE_FLOAT:
					ToT<float>((const char*)value + as_field[i].offset, as_field[i].type, (float*)((char*)data + field[i].offset));
					break;
				case MDB_FIELD_TYPE_DOUBLE:
					ToT<double>((const char*)value + as_field[i].offset, as_field[i].type, (double*)((char*)data + field[i].offset));
					break;
				case MDB_FIELD_TYPE_STRING:
				case MDB_FIELD_TYPE_BLOB:
					ToStr((const char*)value + as_field[i].offset, as_field[i].type, as_field[i].size, (char*)data + field[i].offset, field[i].size);
					break;
				default:
					break;
				}
			}
			return MDB_STATUS_OK;
		}

		template<typename Ty, typename TField>
        static inline MDB_STATUS GetValueAsT(const char* data, const TField* field, size_t field_num, Ty* value)
        {
            if(!data) {
                return MDB_STATUS_INVALID_PARAM;
            }
            if(!field || !field_num || !value) {
                return MDB_STATUS_INVALID_PARAM;
            }
            for(size_t i = 0; i < field_num; i++)
            {
				ASSERT(field[i].size > 0);
				ToT<Ty>((const char*)data + field[i].offset, field[i].type, value + i);
            }
            return MDB_STATUS_OK;
        }

        template<typename Ty, typename TField>
        static inline MDB_STATUS SetValueAsT(char* data, const TField* field, size_t field_num, const Ty* value)
        {
            if(!data) {
                return MDB_STATUS_INVALID_PARAM;
            }
            if(!field || !field_num || !value) {
                return MDB_STATUS_INVALID_PARAM;
            }
			const auto value_type = Type<Ty>();
            for(size_t i = 0; i < field_num; i++)
            {
                ASSERT(field[i].size > 0);
                switch (field[i].type)
                {
                case MDB_FIELD_TYPE_CHAR:
					ToT<char>(value + i, value_type, (char*)((char*)data + field[i].offset));
                    break;
                case MDB_FIELD_TYPE_BYTE:
					ToT<byte>(value + i, value_type, (byte*)((char*)data + field[i].offset));
                    break;
                case MDB_FIELD_TYPE_INT16:
					ToT<int16_t>(value + i, value_type, (int16_t*)((char*)data + field[i].offset));
                    break;
                case MDB_FIELD_TYPE_UINT16:
					ToT<uint16_t>(value + i, value_type, (uint16_t*)((char*)data + field[i].offset));
                    break;
                case MDB_FIELD_TYPE_INT32:
					ToT<int32_t>(value + i, value_type, (int32_t*)((char*)data + field[i].offset));
                    break;
                case MDB_FIELD_TYPE_UINT32:
					ToT<uint32_t>(value + i, value_type, (uint32_t*)((char*)data + field[i].offset));
                    break;
                case MDB_FIELD_TYPE_INT64:
					ToT<int64_t>(value + i, value_type, (int64_t*)((char*)data + field[i].offset));
                    break;
                case MDB_FIELD_TYPE_UINT64:
					ToT<uint64_t>(value + i, value_type, (uint64_t*)((char*)data + field[i].offset));
                    break;
                case MDB_FIELD_TYPE_FLOAT:
					ToT<float>(value + i, value_type, (float*)((char*)data + field[i].offset));
                    break;
                case MDB_FIELD_TYPE_DOUBLE:
					ToT<double>(value + i, value_type, (double*)((char*)data + field[i].offset));
                    break;
                case MDB_FIELD_TYPE_STRING:
				case MDB_FIELD_TYPE_BLOB:
					ToStr(value + i, value_type, sizeof(Ty), (char*)((char*)data + field[i].offset), field[i].size);
                    /*{
                        std::ostrstream ss((char*)data + field[i].offset, field[i].size);
                        ss << value[i];
                    }*/
                    break;
                default:
                    break;
                }
            }
            return MDB_STATUS_OK;
        }

		template<typename TField>
		static inline MDB_STATUS GetValueAsStr(const char* data, const TField* field, size_t field_num, char** value, size_t* size, const char** format)
		{
			if (!data) {
				return MDB_STATUS_INVALID_PARAM;
			}
			if (!field || !field_num || !value || !size) {
				return MDB_STATUS_INVALID_PARAM;
			}
			for (size_t i = 0; i < field_num; i++)
			{
				ToStr((const char*)data + field[i].offset, field[i].type, field[i].size, value[i], size[i], format?format[i]:nullptr);
			}
			return MDB_STATUS_OK;
		}

		template<typename TField>
		static inline MDB_STATUS SetValueAsStr(char* data, const TField* field, size_t field_num, const char** value, const size_t* size)
		{
			if (!data) {
				return MDB_STATUS_INVALID_PARAM;
			}
			if (!field || !field_num || !value) {
				return MDB_STATUS_INVALID_PARAM;
			}
			for (size_t i = 0; i < field_num; i++)
			{
				ASSERT(field[i].size > 0);
				switch (field[i].type)
				{
				case MDB_FIELD_TYPE_CHAR:
					ToT<char>(value[i], MDB_FIELD_TYPE_STRING, (char*)data + field[i].offset);
					break;
				case MDB_FIELD_TYPE_BYTE:
					ToT<byte>(value[i], MDB_FIELD_TYPE_STRING, (byte*)((char*)data + field[i].offset));
					break;
				case MDB_FIELD_TYPE_INT16:
					ToT<int16_t>(value[i], MDB_FIELD_TYPE_STRING, (int16_t*)((char*)data + field[i].offset));
					break;
				case MDB_FIELD_TYPE_UINT16:
					ToT<uint16_t>(value[i], MDB_FIELD_TYPE_STRING, (uint16_t*)((char*)data + field[i].offset));
					break;
				case MDB_FIELD_TYPE_INT32:
					ToT<int32_t>(value[i], MDB_FIELD_TYPE_STRING, (int32_t*)((char*)data + field[i].offset));
					break;
				case MDB_FIELD_TYPE_UINT32:
					ToT<uint32_t>(value[i], MDB_FIELD_TYPE_STRING, (uint32_t*)((char*)data + field[i].offset));
					break;
				case MDB_FIELD_TYPE_INT64:
					ToT<int64_t>(value[i], MDB_FIELD_TYPE_STRING, (int64_t*)((char*)data + field[i].offset));
					break;
				case MDB_FIELD_TYPE_UINT64:
					ToT<uint64_t>(value[i], MDB_FIELD_TYPE_STRING, (uint64_t*)((char*)data + field[i].offset));
					break;
				case MDB_FIELD_TYPE_FLOAT:
					ToT<float>(value[i], MDB_FIELD_TYPE_STRING, (float*)((char*)data + field[i].offset));
					break;
				case MDB_FIELD_TYPE_DOUBLE:
					ToT<double>(value[i], MDB_FIELD_TYPE_STRING, (double*)((char*)data + field[i].offset));
					break;
				case MDB_FIELD_TYPE_STRING:
				case MDB_FIELD_TYPE_BLOB:
					ToStr(value[i], MDB_FIELD_TYPE_STRING, size[i], (char*)data + field[i].offset, field[i].size);
					break;
				default:
					break;
				}
			}
			return MDB_STATUS_OK;
		}
    }

	namespace AttrOp
	{
		template<typename TField>
		inline size_t CalcAttrSize(TField* field, uint32_t field_num)
		{
#if 1
			return sizeof(uint32_t) + sizeof(TField) * field_num;
#else
			size_t attr_sz = 0;
			for (size_t i = 0; i < field_num; i++)
			{
				size_t len = strlen(field[i].name) + 1;
				if (len > sizeof(field[i].buf)) {
					attr_sz += sizeof(MDB_FIELD) + (len - sizeof(field[i].buf));
				}
				else {
					attr_sz += sizeof(MDB_FIELD);
				}
			}
			return sizeof(uint32_t) + attr_sz;
#endif//
		}

		template<typename TField>
		inline size_t CalcSize(TField* field, uint32_t field_num)
		{
			return CalcAttrSize(field, field_num) + MDBFieldCalcSize(field, field_num);
		}

		template<typename TField>
		inline MDB_STATUS InitAttr(char* attr, size_t attr_sz, TField* field, uint32_t field_num)
		{
			if (!attr || !attr_sz || !field || !field_num) {
				return MDB_STATUS_INVALID_PARAM;
			}
			size_t just_attr_sz = CalcAttrSize(field, field_num);
			ASSERT(attr_sz >= just_attr_sz);
			MDBFieldNormalize(field, field_num);
#if 1
			memcpy(attr, &field_num, sizeof(uint32_t));
			memcpy(attr + sizeof(uint32_t), field, sizeof(TField) * field_num);
#else
			char* attr_next = attr;
			memcpy(attr_next, &field_num, sizeof(uint32_t));
			attr_next += sizeof(uint32_t);
			for (size_t i = 0; i < field_num; i++)
			{
				ASSERT(field[i].inner == 0);
				auto len = strlen(field[i].name) + 1;
				auto field_next = (MDB_FIELD*)attr_next;
				memcpy(attr_next, &field[i], sizeof(MDB_FIELD));
				field_next->inner = 1;
				field_next->idx = i;
				field_next->len = len;
				memcpy(field_next->buf, field[i].name, field_next->len);
				field[i].name = field_next->buf;
				if (field_next->len > sizeof(field_next->buf)) {
					attr_next += sizeof(MDB_FIELD) + (field_next->len - sizeof(field_next->buf));
				}
				else {
					attr_next += sizeof(MDB_FIELD);
				}
			}
#endif//
			return MDB_STATUS_OK;
		}

		template<typename TField>
		inline MDB_STATUS Init(char* attr, size_t attr_sz, TField* field, uint32_t field_num, char* data)
		{
			MDB_STATUS ret = InitAttr(attr, attr_sz, field, field_num);
			if (MDB_STATUS_OK != ret) {
				return ret;
			}
			size_t just_attr_sz = CalcAttrSize(field, field_num);
			size_t data_sz = MDBFieldCalcSize(field, field_num);
			ASSERT((just_attr_sz + data_sz) == CalcSize(field, field_num));
			ASSERT(attr_sz >= (just_attr_sz + data_sz));
			if (data) {
				memcpy(attr + just_attr_sz, data, data_sz);
			}
			return MDB_STATUS_OK;
		}

		inline size_t AttrNum(char* attr) { 
			if (!attr) {
				return 0;
			}
			return *(uint32_t*)attr;
		}

		template<typename TField>
		inline auto AttrField(char* attr) -> TField* {
			if (!attr) {
				return nullptr;
			}
			return (TField*)(attr + sizeof(uint32_t));
		}

		template<typename TField>
		inline void* AttrData(char* attr) {
			if (!attr) {
				return nullptr;
			}
			return (attr + CalcAttrSize(AttrField<TField>(attr), AttrNum(attr)));
		}

		inline MDB_STATUS NormalizeField(char* attr, MDB_FIELD* field, uint32_t field_num)
		{
			if (!field || !field_num || !attr) {
				return MDB_STATUS_INVALID_PARAM;
			}
			uint32_t attr_num = AttrNum(attr);
			if (field_num > attr_num) {
				return MDB_STATUS_INVALID_PARAM;
			}
			auto attr_field = AttrField<MDB_FIELD>(attr);
			for (size_t i = 0; i < field_num; i++)
			{
#if 1
				if (field[i].index >= attr_num) {
					return MDB_STATUS_INVALID_PARAM;
				}
				//通过索引获取属性
				field[i] = attr_field[field[i].index];
#else
				MDB_FIELD* attr_next = attr_field;
				if (field[i].inner) {
					//通过索引获取属性
					if (field[i].idx >= attr_num) {
						return MDB_STATUS_INVALID_PARAM;
					}
					for (size_t j = 0; j <= field[i].idx; j++)
					{
						if (attr_next->len > sizeof(attr_next->buf)) {
							attr_next += sizeof(MDB_FIELD) + (attr_next->len - sizeof(attr_next->buf));
						}
						else {
							attr_next += sizeof(MDB_FIELD);
						}
					}
				} else {
					size_t j = 0;
					for (; j < attr_num; j++)
					{
						if (memcmp(field[i].name, attr_next->buf, attr_next->len) == 0) {
							break;
						}
						if (attr_next->len > sizeof(attr_next->buf)) {
							attr_next += sizeof(MDB_FIELD) + (attr_next->len - sizeof(attr_next->buf));
						}
						else {
							attr_next += sizeof(MDB_FIELD);
						}
					}
					if (j >= attr_num) {
						return MDB_STATUS_INVALID_PARAM;
					}
				}
				field[i] = *attr_next;
				field[i].inner = 0;
				field[i].name = attr_next->buf;
#endif//
			}
			return MDB_STATUS_OK;
		}

		inline MDB_STATUS NormalizeNameField(char* attr, MDB_NAME_FIELD* field, uint32_t field_num)
		{
			if (!field || !field_num || !attr) {
				return MDB_STATUS_INVALID_PARAM;
			}
			uint32_t attr_num = AttrNum(attr);
			if (field_num > attr_num) {
				return MDB_STATUS_INVALID_PARAM;
			}
			auto attr_field = AttrField<MDB_NAME_FIELD>(attr);
			for (size_t i = 0; i < field_num; i++)
			{
				size_t j = 0;
				if (field[i].index < MAX_MDB_FIELD_INDEX) {
					//通过索引获取属性
					if (field[i].index >= attr_num) {
						ASSERT(0);
						return MDB_STATUS_INVALID_PARAM;
					}
					field[i] = attr_field[field[i].index];
				}
				else {
					for (; j < attr_num; j++)
					{
						if (strcmp(field[i].name, attr_field[j].name) == 0) {
							field[i] = attr_field[j];
							break;
						}
					}
					if (j >= attr_num) {
						return MDB_STATUS_INVALID_PARAM;
					}
				}
			}
			return MDB_STATUS_OK;
		}

		template<typename TField>
		inline MDB_STATUS GetField(char* attr, TField& field, char* val) {
			return FieldOp::GetValue((const char*)AttrData<TField>(attr), &field, 1, val);
		}
		template<typename Ty, typename TField>
		inline MDB_STATUS GetFieldAsT(char* attr, TField& field, Ty& val) {
			return FieldOp::GetValueAsT((const char*)AttrData<TField>(attr), &field, 1, &val);
		}
		template<typename TField>
		inline MDB_STATUS GetFieldAsStr(char* attr, TField& field, char* val, size_t vallen, const char* format = nullptr) {
			//if (MDB_STATUS_OK == NormalizeField(attr, &field, 1)) {
				char* str[] = {
					val
				};
				size_t str_size[] = {
					vallen
				};
				const char* str_format[] = {
					format
				};
				return FieldOp::GetValueAsStr((const char*)AttrData<TField>(attr), &field, 1, str, str_size, str_format);
			//}
			//return MDB_STATUS_INVALID_PARAM;
		}

		template<typename TField>
		inline MDB_STATUS SetField(char* attr, TField& field, const char* val) {
			return FieldOp::SetValue((char*)AttrData<TField>(attr), &field, 1, val);
		}
		template<typename Ty, typename TField>
		inline MDB_STATUS SetFieldAsT(char* attr, TField& field, const Ty& val) {
			return FieldOp::SetValueAsT((char*)AttrData<TField>(attr), &field, 1, &val);
		}
		template<typename TField>
		inline MDB_STATUS SetFieldAsStr(char* attr, TField& field, const char* val) {
			//if (MDB_STATUS_OK == NormalizeField(attr, &field, 1)) {
				const char* str[] = {
					val
				};
				size_t str_size[] = {
					strlen(val)
				};
				return FieldOp::SetValueAsStr((char*)AttrData<TField>(attr), &field, 1, str, str_size);
			//}
			//return MDB_STATUS_INVALID_PARAM;
		}
	}

	template<class TField>
	class AttrT
	{
		typedef AttrT<TField> This;
	protected:
		std::vector<char> attr_;
	public:
		AttrT(char* attr, size_t attr_sz):attr_(attr, attr + attr_sz)
		{
		}
		AttrT(TField* field, uint32_t field_num, char* data = nullptr)
		{
			attr_.resize(AttrOp::CalcSize(field, field_num));
			AttrOp::Init(attr_.data(), attr_.size(), field, field_num, data);
		}
		AttrT(const This& o) {
			this->attr_ = o.attr_;
		}
		AttrT(This&& o) {
			this->attr_ = std::move(o.attr_);
		}

		inline size_t size() { return attr_.size(); }
		inline char* data() { return attr_.data(); }

		inline size_t Num() { return AttrOp::AttrNum(attr_.data()); }
		inline TField* Field() { return AttrOp::AttrField<TField>(attr_.data()); }
		inline void* Data() { return AttrOp::AttrData<TField>(attr_.data()); }

		inline MDB_STATUS GetField(TField& field, char* val) {
			return AttrOp::GetField(attr_.data(), field, val);
		}
		inline MDB_STATUS SetField(TField& field, const char* val) {
			return AttrOp::SetField(attr_.data(), field, val);
		}
	};

	class Attr : public AttrT<MDB_FIELD>
	{
		typedef AttrT<MDB_FIELD> Base;
	public:
		using Base::Base;

		inline MDB_STATUS NormalizeField(MDB_FIELD* field, uint32_t field_num) {
			return AttrOp::NormalizeField(attr_.data(), field, field_num);
		}

		template<typename Ty, typename TField>
		inline MDB_STATUS GetFieldAsT(TField& field, Ty& val) {
			if (MDB_STATUS_OK == NormalizeField(&field, 1)) {
				return AttrOp::GetFieldAsT(attr_.data(), field, val);
			}
			return MDB_STATUS_INVALID_PARAM;
		}
		template<typename TField>
		inline MDB_STATUS GetFieldAsStr(TField& field, char* val, size_t vallen, const char* format = nullptr) {
			if (MDB_STATUS_OK == NormalizeField(&field, 1)) {
				return AttrOp::GetFieldAsStr(attr_.data(), field, val, vallen, format);
			}
			return MDB_STATUS_INVALID_PARAM;
		}

		template<typename Ty, typename TField>
		inline MDB_STATUS SetFieldAsT(TField& field, const Ty& val) {
			if (MDB_STATUS_OK == NormalizeField(&field, 1)) {
				return AttrOp::SetFieldAsT(attr_.data(), field, val);
			}
			return MDB_STATUS_INVALID_PARAM;
		}
		template<typename TField>
		inline MDB_STATUS SetFieldAsStr(TField& field, const char* val) {
			if (MDB_STATUS_OK == NormalizeField(&field, 1)) {
				return AttrOp::SetFieldAsStr(attr_.data(), field, val);
			}
			return MDB_STATUS_INVALID_PARAM;
		}
	};

	class NameAttr : public AttrT<MDB_NAME_FIELD>
	{
		typedef AttrT<MDB_NAME_FIELD> Base;
	public:
		using Base::Base;

		inline MDB_STATUS NormalizeField(MDB_NAME_FIELD* field, uint32_t field_num) {
			return AttrOp::NormalizeNameField(attr_.data(), field, field_num);
		}

		template<typename Ty, typename TField>
		inline MDB_STATUS GetFieldAsT(TField& field, Ty& val) {
			if (MDB_STATUS_OK == NormalizeField(&field, 1)) {
				return AttrOp::GetFieldAsT(attr_.data(), field, val);
			}
			return MDB_STATUS_INVALID_PARAM;
		}
		template<typename TField>
		inline MDB_STATUS GetFieldAsStr(TField& field, char* val, size_t vallen, const char* format = nullptr) {
			if (MDB_STATUS_OK == NormalizeField(&field, 1)) {
				return AttrOp::GetFieldAsStr(attr_.data(), field, val, vallen, format);
			}
			return MDB_STATUS_INVALID_PARAM;
		}

		template<typename Ty, typename TField>
		inline MDB_STATUS SetFieldAsT(TField& field, const Ty& val) {
			if (MDB_STATUS_OK == NormalizeField(&field, 1)) {
				return AttrOp::SetFieldAsT(attr_.data(), field, val);
			}
			return MDB_STATUS_INVALID_PARAM;
		}
		template<typename TField>
		inline MDB_STATUS SetFieldAsStr(TField& field, const char* val) {
			if (MDB_STATUS_OK == NormalizeField(&field, 1)) {
				return AttrOp::SetFieldAsStr(attr_.data(), field, val);
			}
			return MDB_STATUS_INVALID_PARAM;
		}
	};

#pragma pack(push, 1)

    struct RAW_HEADER
    {
        //ATTR BEGIN
		union {
			uint32_t reserved;
		};
        uint32_t attr_sz;
        uint32_t elem_sz;
        uint32_t elem_off;
        uint32_t elem_num;
        uint32_t max_elem_num;
        //ATTR_DATA
        //ATTR END
        //+
        //VALUE BEGIN
        //ELEM_LIST...
        //VALUE END
    };

#pragma pack(pop)

    namespace DataOp
    {
        inline size_t GetSize(RAW_HEADER* header) { 
            ASSERT(header);
            return sizeof(RAW_HEADER) + header->attr_sz + header->elem_sz * header->max_elem_num;
        }

        inline char* GetAttr(RAW_HEADER* header) { 
            ASSERT(header);
            return (char*)(header + 1);
        }

        inline char* GetValue(RAW_HEADER* header) { 
            ASSERT(header);
            return (char*)GetAttr(header) + header->attr_sz;
        }
        inline char* GetValueByAbsolutePos(RAW_HEADER* header, size_t pos) { 
            ASSERT(header);
            ASSERT(pos < header->max_elem_num);
            return (char*)GetValue(header) + header->elem_sz * pos;
        }
        inline size_t ToAbsolutePos(RAW_HEADER* header, ssize_t pos)
        {
            pos += header->elem_off;
            if(pos >= header->max_elem_num) {
                pos -= header->max_elem_num;
            } else if(pos < 0) {
				pos += header->max_elem_num;
			}
			ASSERT(pos < header->max_elem_num);
            return pos;
        }
        inline char* GetValueByRelativePos(RAW_HEADER* header, size_t pos) { 
            ASSERT(header);
			//ASSERT(pos < header->elem_num);
            return (char*)GetValue(header) + header->elem_sz * ToAbsolutePos(header, pos);
        }
		//这里是循环表结构，first第一块内存，second第二块内存
		//|||second|||---space----|||first||||
		inline bool IsValueDivided(RAW_HEADER* header, size_t *first = nullptr, size_t *second = nullptr) {
			if((header->elem_off + header->elem_num) > header->max_elem_num) {
				if (first)
					*first = header->max_elem_num - header->elem_off;
				if(second)
					*second = (header->elem_off + header->elem_num) - header->max_elem_num;
				return true;
			}
			return false;
		}
		//|||second|||---data----|||first||||
		inline bool IsSpaceDivided(RAW_HEADER* header, size_t *first = nullptr, size_t *second = nullptr) {
			if(header->elem_off > 0 && (header->elem_off + header->elem_num) < header->max_elem_num) {
				if(first)
					*first = header->max_elem_num - (header->elem_off + header->elem_num);
				if(second)
					*second = header->elem_off;
				return true;
			}
			return false;
		}
		//||||||---space----|||pos-first|||
		inline bool IsRelativePosInFirst(RAW_HEADER* header, size_t pos, size_t* abs_pos = nullptr) {
			if((header->elem_off + pos) < header->max_elem_num) {
				if(abs_pos)
					*abs_pos = header->elem_off + pos;
				return true;
			}
			return false;
		}
		//|||pos-second|||---space----||||||
		inline bool IsRelativePosInSecond(RAW_HEADER* header, size_t pos, size_t* abs_pos = nullptr) {
			if((header->elem_off + pos) >= header->max_elem_num) {
				if(abs_pos)
					*abs_pos = (header->elem_off + pos) - header->max_elem_num;
				return true;
			}
			return false;
		}
		//|||second-pos+num|||---space----|||pos-first|||
		inline bool IsRangeDivided(RAW_HEADER* header, size_t pos, size_t num, size_t *first = nullptr, size_t *second = nullptr) {
			BOOST_ASSERT((header->elem_off + pos) < 2 * header->max_elem_num);
			if (num > 1) {
				if ((header->elem_off + pos) < header->max_elem_num 
					&& (header->elem_off + pos + num - 1/*最后一个有效元素位置是pos + num - 1*/) >= header->max_elem_num) {
					if (first)
						*first = header->max_elem_num - (header->elem_off + pos);
					if (second)
						*second = (header->elem_off + pos + num) - header->max_elem_num;
					return true;
				}
			}
			return false;
		}

        inline size_t CalcSize(size_t attr_sz, size_t elem_sz, size_t max_elem_num, bool ptr) 
        {
			if (ptr) {
				return sizeof(RAW_HEADER) + attr_sz;
			}
            return sizeof(RAW_HEADER) + attr_sz + elem_sz * max_elem_num;
        }
        
        inline MDB_STATUS Init(RAW_HEADER* header, size_t data_sz, char* attr, size_t attr_sz, char* elem, size_t elem_sz, size_t elem_num, size_t max_elem_num, size_t reserved, bool ptr)
        {
            if(!header) {
                return MDB_STATUS_MEM_OVERFLOW;
            }
            BOOST_ASSERT(elem_num<=max_elem_num);
            BOOST_ASSERT(data_sz >= CalcSize(attr_sz, elem_sz, max_elem_num, ptr));
            memset(header, 0, data_sz);
			header->reserved = reserved;
			header->attr_sz = attr_sz;
			if (attr) {
				memcpy(GetAttr(header), attr, attr_sz);
			}
			header->elem_sz = elem_sz;
			header->elem_off = 0;
			if (!ptr && elem) {
				memcpy(GetValue(header), elem, elem_sz * elem_num);
			}
			header->elem_num = elem_num;
            header->max_elem_num = max_elem_num;
            return MDB_STATUS_OK;
        }

		inline MDB_STATUS ReInit(RAW_HEADER* header, size_t data_sz, char* attr, size_t attr_sz, char* elem, size_t elem_sz, size_t elem_num, size_t max_elem_num, size_t reserved, bool ptr)
		{
			if (!header) {
				return MDB_STATUS_MEM_OVERFLOW;
			}
			BOOST_ASSERT(elem_num <= max_elem_num);
			BOOST_ASSERT(data_sz >= CalcSize(attr_sz, elem_sz, max_elem_num, ptr));
			header->reserved = reserved;
			if (header->attr_sz != attr_sz || header->elem_sz != elem_sz
				|| (elem && elem_num)
				|| (header->max_elem_num != max_elem_num && header->elem_off)) {
				header->attr_sz = attr_sz;
				if (attr) {
					memcpy(GetAttr(header), attr, attr_sz);
				}
				header->elem_sz = elem_sz;
				header->elem_off = 0;
				if (!ptr && elem) {
					memcpy(GetValue(header), elem, elem_sz * elem_num);
				}
				header->elem_num = elem_num;
			}
			header->max_elem_num = max_elem_num;
			return MDB_STATUS_OK;
		}

		// _FwdIt _Lower_bound_unchecked(_FwdIt _First, _FwdIt _Last,
		// 	const _Ty& _Val, _Pr& _Pred)
		// {	// find first element not before _Val, using _Pred
		// _Iter_diff_t<_FwdIt> _Count = _STD distance(_First, _Last);

		// while (0 < _Count)
		// 	{	// divide and conquer, find half that contains answer
		// 	_Iter_diff_t<_FwdIt> _Count2 = _Count / 2;
		// 	_FwdIt _Mid = _First;
		// 	_STD advance(_Mid, _Count2);

		// 	if (_Pred(*_Mid, _Val))
		// 		{	// try top half
		// 		_First = ++_Mid;
		// 		_Count -= _Count2 + 1;
		// 		}
		// 	else
		// 		_Count = _Count2;
		// 	}

		// return (_First);
		// }
		template<typename TField>
		inline size_t LowerBound(RAW_HEADER* header, TField* field, size_t field_num, size_t first, size_t last, const char* data)
		{
			size_t count = last - first;
			while (0 < count)
			{
				size_t count2 = count / 2;
				if (FieldOp::Less(field, field_num, GetValueByRelativePos(header, count2), data)) {
					// try top half
					first = ++count2;
					count -= count2;
				} else {
					count = count2;
				}
			}
			return first;
		}

		// template<class _FwdIt,
		// class _Ty,
		// class _Pr> inline
		// _FwdIt _Upper_bound_unchecked(_FwdIt _First, _FwdIt _Last,
		// 	const _Ty& _Val, _Pr& _Pred)
		// {	// find first element that _Val is before, using _Pred
		// _Iter_diff_t<_FwdIt> _Count = _STD distance(_First, _Last);

		// while (0 < _Count)
		// 	{	// divide and conquer, find half that contains answer
		// 	_Iter_diff_t<_FwdIt> _Count2 = _Count / 2;
		// 	_FwdIt _Mid = _First;
		// 	_STD advance(_Mid, _Count2);

		// 	if (!_Pred(_Val, *_Mid))
		// 		{	// try top half
		// 		_First = ++_Mid;
		// 		_Count -= _Count2 + 1;
		// 		}
		// 	else
		// 		_Count = _Count2;
		// 	}

		// return (_First);
		// }
		template<typename TField>
		inline size_t UpperBound(RAW_HEADER* header, TField* field, size_t field_num, size_t first, size_t last, char* data)
		{
			size_t count = last - first;
			while (0 < count)
			{
				size_t count2 = count / 2;
				if (FieldOp::Less(field, field_num, data, GetValueByRelativePos(header, count2))) {
					// try top half
					first = ++count2;
					count -= count2;
				} else {
					count = count2;
				}
			}
			return first;
		}

		// template<class _FwdIt,
		// class _Ty,
		// class _Pr> inline
		// pair<_FwdIt, _FwdIt>
		// 	_Equal_range_unchecked(_FwdIt _First, _FwdIt _Last,
		// 		const _Ty& _Val, _Pr& _Pred)
		// {	// find range equivalent to _Val, using _Pred
		// _Iter_diff_t<_FwdIt> _Count = _STD distance(_First, _Last);

		// while (0 < _Count)
		// 	{	// divide and conquer, check midpoint
		// 	_Iter_diff_t<_FwdIt> _Count2 = _Count / 2;
		// 	_FwdIt _Mid = _First;
		// 	_STD advance(_Mid, _Count2);

		// 	if (_DEBUG_LT_PRED(_Pred, *_Mid, _Val))
		// 		{	// range begins above _Mid, loop
		// 		_First = ++_Mid;
		// 		_Count -= _Count2 + 1;
		// 		}
		// 	else if (_Pred(_Val, *_Mid))
		// 		_Count = _Count2;	// range in first half, loop
		// 	else
		// 		{	// range straddles _Mid, find each end and return
		// 		_FwdIt _First2 = _Lower_bound_unchecked(_First, _Mid, _Val, _Pred);
		// 		_STD advance(_First, _Count);
		// 		_FwdIt _Last2 = _Upper_bound_unchecked(++_Mid, _First, _Val, _Pred);
		// 		return (pair<_FwdIt, _FwdIt>(_First2, _Last2));
		// 		}
		// 	}

		// return (pair<_FwdIt, _FwdIt>(_First, _First));	// empty range
		// }
		template<typename TField>
		inline std::pair<size_t,size_t> EqualRange(RAW_HEADER* header, TField* field, size_t field_num, size_t first, size_t last, char* data)
		{
			size_t count = last - first;
			while (0 < count)
			{
				size_t count2 = count / 2;
				if (FieldOp::Less(field, field_num, data, GetValueByRelativePos(header, count2))) {
					// try top half
					first = ++count2;
					count -= count2;
				} else if(FieldOp::Less(field, field_num, GetValueByRelativePos(header, count2), data)) {
					count = count2;
				} else {
					size_t first2 = LowerBound(header, field, field_num, first, count2, data);
					size_t last2 = UpperBound(header, field, field_num, ++count2, last, data);
					return (std::pair<size_t, size_t>(first2, last2));
				}
			}
			return std::pair<size_t,size_t>(first,first);
		}

		inline MDB_STATUS UpdateValue(RAW_HEADER* header, size_t pos, const char* elem, size_t num, bool cycle)
		{
			if (!elem || num <= 0) {
				return MDB_STATUS_INVALID_PARAM;
			}
			if ((pos + num) > header->elem_num) {
				return MDB_STATUS_INVALID_PARAM;
			}
			if (cycle) {
				size_t first = 0, second = 0;
				if (IsRangeDivided(header, pos, num, &first, &second)) {
					BOOST_ASSERT((first + second) == num);
					memcpy(GetValueByRelativePos(header, pos), elem, first * header->elem_sz);
					memcpy(GetValueByAbsolutePos(header, 0), elem + first * header->elem_sz, second * header->elem_sz);
					return MDB_STATUS_OK;
				}
			}
			memcpy(GetValueByRelativePos(header, pos), elem, header->elem_sz * num);
			return MDB_STATUS_OK;
		}
		inline MDB_STATUS CopyValue(RAW_HEADER* header, size_t pos, char* elem, size_t& num, bool cycle) {
			if (pos >= header->elem_num || !elem || num <= 0) {
				return MDB_STATUS_INVALID_PARAM;
			}
			if ((pos + num) >= header->elem_num) {
				num = header->elem_num - pos;
			}
			if (num <= 0) {
				return MDB_STATUS_OK;
			}
			if (cycle) {
				size_t first = 0, second = 0;
				if (IsRangeDivided(header, pos, num, &first, &second)) {
					BOOST_ASSERT((first + second) == num);
					memcpy(elem, GetValueByRelativePos(header, pos), first * header->elem_sz);
					memcpy(elem + first * header->elem_sz, GetValueByAbsolutePos(header, 0), second * header->elem_sz);
					return MDB_STATUS_OK;
				}
			}
			memcpy(elem, GetValueByRelativePos(header, pos), num * header->elem_sz);
			return MDB_STATUS_OK;
		}
		inline MDB_STATUS ResizeValue(RAW_HEADER* header, size_t num, bool cycle)
		{
			if (num < 0) {
				return MDB_STATUS_INVALID_PARAM;
			}
			size_t new_num = num;
			if (new_num > header->max_elem_num) {
				return MDB_STATUS_MEM_OVERFLOW;
			}
			header->elem_num = new_num;
			return MDB_STATUS_OK;
		}
		inline MDB_STATUS AppendValue(RAW_HEADER* header, const char* elem, size_t num, bool cycle)
		{
			if (!elem || num <= 0) {
				return MDB_STATUS_INVALID_PARAM;
			}
			size_t new_num = header->elem_num + num;
			if (cycle) {
				if (new_num > header->max_elem_num) {
					if(num > header->max_elem_num) {
						elem += header->elem_sz * (num - header->max_elem_num);
						num = header->max_elem_num;
						memcpy(GetValueByAbsolutePos(header, 0), elem, header->elem_sz * num);
						header->elem_off = 0;
						header->elem_num = num;
						return MDB_STATUS_OK;
					} else {
						size_t off = (new_num - header->max_elem_num);
						header->elem_off = ToAbsolutePos(header, off);
						header->elem_num = header->max_elem_num;
						return UpdateValue(header, header->elem_num - num, elem, num, cycle);
					}
				} else {
					size_t off = header->elem_num;
					header->elem_num = new_num;
					return UpdateValue(header, off, elem, num, cycle);
				}
			} else {
				if (new_num > header->max_elem_num) {
					return MDB_STATUS_MEM_OVERFLOW;
				}
			}
			memcpy(GetValueByRelativePos(header, header->elem_num), elem, header->elem_sz * num);
			header->elem_num = new_num;
			return MDB_STATUS_OK;
		}
        inline MDB_STATUS InsertValue(RAW_HEADER* header, size_t pos, const char* elem, size_t num, bool cycle)
        {
            if(pos >= header->elem_num) {
                return AppendValue(header, elem, num, cycle);
            }
            if(!elem || num <= 0) {
                return MDB_STATUS_INVALID_PARAM;
            }
            size_t new_num = header->elem_num + num;
            if(cycle) {
				BOOST_ASSERT(0);//没有测试过
				size_t reserved_num = header->elem_num - pos;
				size_t unused_num = header->max_elem_num - header->elem_num;
				size_t max_usable_num = header->max_elem_num - reserved_num;
				if (max_usable_num <= 0) {
					return MDB_STATUS_MEM_OVERFLOW;
				}
				if (new_num > max_usable_num) {
					if(num > max_usable_num) {
						elem += header->elem_sz * (num - max_usable_num);
						num = max_usable_num;
						new_num = header->max_elem_num;
						header->elem_off = ToAbsolutePos(header, header->elem_num);
						header->elem_num = new_num;
						return UpdateValue(header, 0, elem, num, cycle);
					} else {
						size_t off = new_num - max_usable_num;
						elem += header->elem_sz * off;
						num -= off;
						new_num = header->max_elem_num;
						header->elem_off = ToAbsolutePos(header, header->elem_num);
						header->elem_num = new_num;
						return UpdateValue(header, 0, elem, num, cycle);
					}
				} else {
					ssize_t off = unused_num - num;
					if (off < 0) {
						header->elem_off = ToAbsolutePos(header, off);
						header->elem_num = new_num;
						return UpdateValue(header, 0, elem, num, cycle);
					}
					else {
						header->elem_num = new_num;
						UpdateValue(header, pos + num, GetValueByRelativePos(header, pos), header->elem_num - pos, cycle);
						UpdateValue(header, pos, elem, num, cycle);
						return MDB_STATUS_OK;
					}
				}
            } else {
				if(new_num > header->max_elem_num) {
					return MDB_STATUS_MEM_OVERFLOW;
				}
			}
            memmove(GetValueByRelativePos(header, pos + num), GetValueByRelativePos(header, pos), header->elem_sz * (header->elem_num-pos));
            memcpy(GetValueByRelativePos(header, pos), elem, header->elem_sz * num);
            header->elem_num = new_num;
            return MDB_STATUS_OK;
        }
        /*inline MDB_STATUS InsertValue(RAW_HEADER* header, const char* elem, size_t num, bool cycle)
        {
            if(!elem || num <= 0) {
                return MDB_STATUS_INVALID_PARAM;
            }
            size_t new_num = header->elem_num + num;
            if(cycle) {
			} else {
				if(new_num > header->max_elem_num) {
					return MDB_STATUS_MEM_OVERFLOW;
				}
			}
			for(size_t i = 0; i < num; i++)
			{
				size_t pos = LowerBound(header, MDB_FIELD_INDEX_LEVEL1, 0, header->elem_num, elem + header->elem_sz * i);
				InsertValue(header, pos, elem + header->elem_sz * i, 1);
			}
            return MDB_STATUS_OK;
        }*/
        inline MDB_STATUS RemoveValue(RAW_HEADER* header, size_t pos, size_t& num, bool cycle)
        {
            if(pos >= header->elem_num || num <= 0) {
                return MDB_STATUS_INVALID_PARAM;
            }

			//简单处理循环表，只支持删除前后数据
			if (cycle) {
				if (pos == 0) {
					//删除前面
					if (num >= header->elem_num) {
						header->elem_off = 0;
						header->elem_num = 0;
					}
					else {
						header->elem_off = ToAbsolutePos(header, num);
						header->elem_num -= num;
					}
				}
				else {
					//删除后面
					header->elem_num = pos;
				}
				return MDB_STATUS_OK;
			}

            size_t rm_end = pos + num;
            if(rm_end >= header->elem_num) {
                header->elem_num = pos;
            } else if(rm_end < header->elem_num) {
                size_t rm_num = header->elem_num - rm_end;
                memmove(GetValueByRelativePos(header, pos), GetValueByRelativePos(header, rm_end), header->elem_sz * rm_num);
                header->elem_num -= num;
            }
            return MDB_STATUS_OK;
        }
		inline MDB_STATUS ClearValue(RAW_HEADER* header, size_t& num, bool cycle)
		{
			num = header->elem_num;
			header->elem_off = 0;
			header->elem_num = 0;
			return MDB_STATUS_OK;
		}
    }

#pragma pack(push, 1)

	struct COL_HEADER
	{
		union {
			uint32_t reserved;
		};
		MDB_COL_FIELD col;
		//VALUE BEGIN
		//ELEM_LIST...
		//VALUE END
	};

#pragma pack(pop)

	namespace ColDataOp
	{
		inline size_t GetSize(COL_HEADER* header) {
			ASSERT(header);
			return sizeof(COL_HEADER) + header->col.size * header->col.max_count;
		}

		inline char* GetValue(COL_HEADER* header) {
			ASSERT(header);
			return (char*)(header + 1);
		}
		inline char* GetValueByAbsolutePos(COL_HEADER* header, size_t pos) {
			ASSERT(header);
			ASSERT(pos < header->col.max_count);
			return (char*)GetValue(header) + header->col.size * pos;
		}
		inline size_t ToAbsolutePos(COL_HEADER* header, ssize_t pos)
		{
			pos += header->col.offset;
			if (pos >= header->col.max_count) {
				pos -= header->col.max_count;
			}
			else if (pos < 0) {
				pos += header->col.max_count;
			}
			ASSERT(pos < header->col.max_count);
			return pos;
		}
		inline char* GetValueByRelativePos(COL_HEADER* header, size_t pos) {
			ASSERT(header);
			//ASSERT(pos < header->col.count);
			return (char*)GetValue(header) + header->col.size * ToAbsolutePos(header, pos);
		}
		//这里是循环表结构，first第一块内存，second第二块内存
		//|||second|||---space----|||first||||
		inline bool IsValueDivided(COL_HEADER* header, size_t *first = nullptr, size_t *second = nullptr) {
			if ((header->col.offset + header->col.count) > header->col.max_count) {
				if (first)
					*first = header->col.max_count - header->col.offset;
				if (second)
					*second = (header->col.offset + header->col.count) - header->col.max_count;
				return true;
			}
			return false;
		}
		//|||second|||---data----|||first||||
		inline bool IsSpaceDivided(COL_HEADER* header, size_t *first = nullptr, size_t *second = nullptr) {
			if (header->col.offset > 0 && (header->col.offset + header->col.count) < header->col.max_count) {
				if (first)
					*first = header->col.max_count - (header->col.offset + header->col.count);
				if (second)
					*second = header->col.offset;
				return true;
			}
			return false;
		}
		//||||||---space----|||pos-first|||
		inline bool IsRelativePosInFirst(COL_HEADER* header, size_t pos, size_t* abs_pos = nullptr) {
			if ((header->col.offset + pos) < header->col.max_count) {
				if (abs_pos)
					*abs_pos = header->col.offset + pos;
				return true;
			}
			return false;
		}
		//|||pos-second|||---space----||||||
		inline bool IsRelativePosInSecond(COL_HEADER* header, size_t pos, size_t* abs_pos = nullptr) {
			if ((header->col.offset + pos) >= header->col.max_count) {
				if (abs_pos)
					*abs_pos = (header->col.offset + pos) - header->col.max_count;
				return true;
			}
			return false;
		}
		//|||second-pos+num|||---space----|||pos-first|||
		inline bool IsRangeDivided(COL_HEADER* header, size_t pos, size_t num, size_t *first = nullptr, size_t *second = nullptr) {
			BOOST_ASSERT((header->col.offset + pos) < 2 * header->col.max_count);
			if (num > 1) {
				if ((header->col.offset + pos) < header->col.max_count
					&& (header->col.offset + pos + num - 1/*最后一个有效元素位置是pos + num - 1*/) >= header->col.max_count) {
					if (first)
						*first = header->col.max_count - (header->col.offset + pos);
					if (second)
						*second = (header->col.offset + pos + num) - header->col.max_count;
					return true;
				}
			}
			return false;
		}

		inline size_t CalcSize(MDB_COL_FIELD& attr)
		{
			return sizeof(COL_HEADER) + attr.size * attr.max_count;
		}

		inline MDB_STATUS Init(COL_HEADER* header, size_t data_sz, MDB_TABLE_TYPE type, MDB_COL_FIELD& attr, size_t reserved = 0)
		{
			if (!header) {
				return MDB_STATUS_MEM_OVERFLOW;
			}
			BOOST_ASSERT(data_sz >= CalcSize(attr));
			memset(header, 0, data_sz);
			header->reserved = reserved;
			if (header->col.type != attr.type || header->col.size != attr.size
				|| (header->col.max_count != attr.max_count && header->col.offset)) {
				header->col = attr;
				header->col.offset = 0;
				header->col.count = 0;
			}
			else {
				header->col.max_count = attr.max_count;
			}
			return MDB_STATUS_OK;
		}

		// _FwdIt _Lower_bound_unchecked(_FwdIt _First, _FwdIt _Last,
		// 	const _Ty& _Val, _Pr& _Pred)
		// {	// find first element not before _Val, using _Pred
		// _Iter_diff_t<_FwdIt> _Count = _STD distance(_First, _Last);

		// while (0 < _Count)
		// 	{	// divide and conquer, find half that contains answer
		// 	_Iter_diff_t<_FwdIt> _Count2 = _Count / 2;
		// 	_FwdIt _Mid = _First;
		// 	_STD advance(_Mid, _Count2);

		// 	if (_Pred(*_Mid, _Val))
		// 		{	// try top half
		// 		_First = ++_Mid;
		// 		_Count -= _Count2 + 1;
		// 		}
		// 	else
		// 		_Count = _Count2;
		// 	}

		// return (_First);
		// }
		inline size_t LowerBound(COL_HEADER* header, size_t first, size_t last, const char* data)
		{
			size_t count = last - first;
			while (0 < count)
			{
				size_t count2 = count / 2;
				if (FieldOp::Less(&header->col, 1, GetValueByRelativePos(header, count2), data)) {
					// try top half
					first = ++count2;
					count -= count2;
				}
				else {
					count = count2;
				}
			}
			return first;
		}

		// template<class _FwdIt,
		// class _Ty,
		// class _Pr> inline
		// _FwdIt _Upper_bound_unchecked(_FwdIt _First, _FwdIt _Last,
		// 	const _Ty& _Val, _Pr& _Pred)
		// {	// find first element that _Val is before, using _Pred
		// _Iter_diff_t<_FwdIt> _Count = _STD distance(_First, _Last);

		// while (0 < _Count)
		// 	{	// divide and conquer, find half that contains answer
		// 	_Iter_diff_t<_FwdIt> _Count2 = _Count / 2;
		// 	_FwdIt _Mid = _First;
		// 	_STD advance(_Mid, _Count2);

		// 	if (!_Pred(_Val, *_Mid))
		// 		{	// try top half
		// 		_First = ++_Mid;
		// 		_Count -= _Count2 + 1;
		// 		}
		// 	else
		// 		_Count = _Count2;
		// 	}

		// return (_First);
		// }
		inline size_t UpperBound(COL_HEADER* header, size_t first, size_t last, char* data)
		{
			size_t count = last - first;
			while (0 < count)
			{
				size_t count2 = count / 2;
				if (FieldOp::Less(&header->col, 1, data, GetValueByRelativePos(header, count2))) {
					// try top half
					first = ++count2;
					count -= count2;
				}
				else {
					count = count2;
				}
			}
			return first;
		}

		// template<class _FwdIt,
		// class _Ty,
		// class _Pr> inline
		// pair<_FwdIt, _FwdIt>
		// 	_Equal_range_unchecked(_FwdIt _First, _FwdIt _Last,
		// 		const _Ty& _Val, _Pr& _Pred)
		// {	// find range equivalent to _Val, using _Pred
		// _Iter_diff_t<_FwdIt> _Count = _STD distance(_First, _Last);

		// while (0 < _Count)
		// 	{	// divide and conquer, check midpoint
		// 	_Iter_diff_t<_FwdIt> _Count2 = _Count / 2;
		// 	_FwdIt _Mid = _First;
		// 	_STD advance(_Mid, _Count2);

		// 	if (_DEBUG_LT_PRED(_Pred, *_Mid, _Val))
		// 		{	// range begins above _Mid, loop
		// 		_First = ++_Mid;
		// 		_Count -= _Count2 + 1;
		// 		}
		// 	else if (_Pred(_Val, *_Mid))
		// 		_Count = _Count2;	// range in first half, loop
		// 	else
		// 		{	// range straddles _Mid, find each end and return
		// 		_FwdIt _First2 = _Lower_bound_unchecked(_First, _Mid, _Val, _Pred);
		// 		_STD advance(_First, _Count);
		// 		_FwdIt _Last2 = _Upper_bound_unchecked(++_Mid, _First, _Val, _Pred);
		// 		return (pair<_FwdIt, _FwdIt>(_First2, _Last2));
		// 		}
		// 	}

		// return (pair<_FwdIt, _FwdIt>(_First, _First));	// empty range
		// }
		inline std::pair<size_t, size_t> EqualRange(COL_HEADER* header, size_t first, size_t last, char* data)
		{
			size_t count = last - first;
			while (0 < count)
			{
				size_t count2 = count / 2;
				if (FieldOp::Less(&header->col, 1, data, GetValueByRelativePos(header, count2))) {
					// try top half
					first = ++count2;
					count -= count2;
				}
				else if (FieldOp::Less(&header->col, 1, GetValueByRelativePos(header, count2), data)) {
					count = count2;
				}
				else {
					size_t first2 = LowerBound(header, first, count2, data);
					size_t last2 = UpperBound(header, ++count2, last, data);
					return (std::pair<size_t, size_t>(first2, last2));
				}
			}
			return std::pair<size_t, size_t>(first, first);
		}

		inline MDB_STATUS UpdateValue(COL_HEADER* header, size_t pos, const char* elem, size_t num, bool cycle)
		{
			if (!elem || num <= 0) {
				return MDB_STATUS_INVALID_PARAM;
			}
			if ((pos + num) > header->col.count) {
				return MDB_STATUS_INVALID_PARAM;
			}
			if (cycle) {
				size_t first = 0, second = 0;
				if (IsRangeDivided(header, pos, num, &first, &second)) {
					BOOST_ASSERT((first + second) == num);
					memcpy(GetValueByRelativePos(header, pos), elem, first * header->col.size);
					memcpy(GetValueByAbsolutePos(header, 0), elem + first * header->col.size, second * header->col.size);
					return MDB_STATUS_OK;
				}
			}
			memcpy(GetValueByRelativePos(header, pos), elem, header->col.size * num);
			return MDB_STATUS_OK;
		}
		inline MDB_STATUS CopyValue(COL_HEADER* header, size_t pos, char* elem, size_t& num, bool cycle) {
			if (pos >= header->col.count || !elem || num <= 0) {
				return MDB_STATUS_INVALID_PARAM;
			}
			if ((pos + num) >= header->col.count) {
				num = header->col.count - pos;
			}
			if (num <= 0) {
				return MDB_STATUS_OK;
			}
			if (cycle) {
				size_t first = 0, second = 0;
				if (IsRangeDivided(header, pos, num, &first, &second)) {
					BOOST_ASSERT((first + second) == num);
					memcpy(elem, GetValueByRelativePos(header, pos), first * header->col.size);
					memcpy(elem + first * header->col.size, GetValueByAbsolutePos(header, 0), second * header->col.size);
					return MDB_STATUS_OK;
				}
			}
			memcpy(elem, GetValueByRelativePos(header, pos), num * header->col.size);
			return MDB_STATUS_OK;
		}
		inline MDB_STATUS ResizeValue(COL_HEADER* header, size_t num, bool cycle)
		{
			if (num < 0) {
				return MDB_STATUS_INVALID_PARAM;
			}
			size_t new_num = num;
			if (new_num > header->col.max_count) {
				return MDB_STATUS_MEM_OVERFLOW;
			}
			header->col.count = new_num;
			return MDB_STATUS_OK;
		}
		inline MDB_STATUS AppendValue(COL_HEADER* header, const char* elem, size_t num, bool cycle)
		{
			if (!elem || num <= 0) {
				return MDB_STATUS_INVALID_PARAM;
			}
			size_t new_num = header->col.count + num;
			if (cycle) {
				if (new_num > header->col.max_count) {
					if (num > header->col.max_count) {
						elem += header->col.size * (num - header->col.max_count);
						num = header->col.max_count;
						memcpy(GetValueByAbsolutePos(header, 0), elem, header->col.size * num);
						header->col.offset = 0;
						header->col.count = num;
						return MDB_STATUS_OK;
					}
					else {
						size_t off = (new_num - header->col.max_count);
						header->col.offset = ToAbsolutePos(header, off);
						header->col.count = header->col.max_count;
						return UpdateValue(header, header->col.count - num, elem, num, cycle);
					}
				}
				else {
					size_t off = header->col.count;
					header->col.count = new_num;
					return UpdateValue(header, off, elem, num, cycle);
				}
			}
			else {
				if (new_num > header->col.max_count) {
					return MDB_STATUS_MEM_OVERFLOW;
				}
			}
			memcpy(GetValueByRelativePos(header, header->col.count), elem, header->col.size * num);
			header->col.count = new_num;
			return MDB_STATUS_OK;
		}
		inline MDB_STATUS InsertValue(COL_HEADER* header, size_t pos, const char* elem, size_t num, bool cycle)
		{
			if (pos >= header->col.count) {
				return AppendValue(header, elem, num, cycle);
			}
			if (!elem || num <= 0) {
				return MDB_STATUS_INVALID_PARAM;
			}
			size_t new_num = header->col.count + num;
			if (cycle) {
				BOOST_ASSERT(0);//没有测试过
				size_t reserved_num = header->col.count - pos;
				size_t unused_num = header->col.max_count - header->col.count;
				size_t max_usable_num = header->col.max_count - reserved_num;
				if (max_usable_num <= 0) {
					return MDB_STATUS_MEM_OVERFLOW;
				}
				if (new_num > max_usable_num) {
					if (num > max_usable_num) {
						elem += header->col.size * (num - max_usable_num);
						num = max_usable_num;
						new_num = header->col.max_count;
						header->col.offset = ToAbsolutePos(header, header->col.count);
						header->col.count = new_num;
						return UpdateValue(header, 0, elem, num, cycle);
					}
					else {
						size_t off = new_num - max_usable_num;
						elem += header->col.size * off;
						num -= off;
						new_num = header->col.max_count;
						header->col.offset = ToAbsolutePos(header, header->col.count);
						header->col.count = new_num;
						return UpdateValue(header, 0, elem, num, cycle);
					}
				}
				else {
					ssize_t off = unused_num - num;
					if (off < 0) {
						header->col.offset = ToAbsolutePos(header, off);
						header->col.count = new_num;
						return UpdateValue(header, 0, elem, num, cycle);
					}
					else {
						header->col.count = new_num;
						UpdateValue(header, pos + num, GetValueByRelativePos(header, pos), header->col.count - pos, cycle);
						UpdateValue(header, pos, elem, num, cycle);
						return MDB_STATUS_OK;
					}
				}
			}
			else {
				if (new_num > header->col.max_count) {
					return MDB_STATUS_MEM_OVERFLOW;
				}
			}
			memmove(GetValueByRelativePos(header, pos + num), GetValueByRelativePos(header, pos), header->col.size * (header->col.count - pos));
			memcpy(GetValueByRelativePos(header, pos), elem, header->col.size * num);
			header->col.count = new_num;
			return MDB_STATUS_OK;
		}
		/*inline MDB_STATUS InsertValue(COL_HEADER* header, const char* elem, size_t num, bool cycle)
		{
		if(!elem || num <= 0) {
		return MDB_STATUS_INVALID_PARAM;
		}
		size_t new_num = header->col.count + num;
		if(cycle) {
		} else {
		if(new_num > header->col.max_count) {
		return MDB_STATUS_MEM_OVERFLOW;
		}
		}
		for(size_t i = 0; i < num; i++)
		{
		size_t pos = LowerBound(header, MDB_FIELD_INDEX_LEVEL1, 0, header->col.count, elem + header->col.size * i);
		InsertValue(header, pos, elem + header->col.size * i, 1);
		}
		return MDB_STATUS_OK;
		}*/
		inline MDB_STATUS RemoveValue(COL_HEADER* header, size_t pos, size_t& num, bool cycle)
		{
			if (pos >= header->col.count || num <= 0) {
				return MDB_STATUS_INVALID_PARAM;
			}

			//简单处理循环表，只支持删除前后数据
			if (cycle) {
				if (pos == 0) {
					//删除前面
					if (num >= header->col.count) {
						header->col.offset = 0;
						header->col.count = 0;
					}
					else {
						header->col.offset = ToAbsolutePos(header, num);
						header->col.count -= num;
					}
				}
				else {
					//删除后面
					header->col.count = pos;
				}
				return MDB_STATUS_OK;
			}

			size_t rm_end = pos + num;
			if (rm_end >= header->col.count) {
				header->col.count = pos;
			}
			else if (rm_end < header->col.count) {
				size_t rm_num = header->col.count - rm_end;
				memmove(GetValueByRelativePos(header, pos), GetValueByRelativePos(header, rm_end), header->col.size * rm_num);
				header->col.count -= num;
			}
			return MDB_STATUS_OK;
		}
	}

} // namespace mdb


